package com.pj.compose.ui.compose

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.navigation.compose.rememberNavController
import com.pj.compose.ui.page.widget.*
import com.pj.compose.ui.theme.c3367D5

/**
 * 弹窗的类型
 */
enum class DialogType {
    //仅文本的对话框
    MESSAGE,

    //长文本
    LONG_MESSAGE,

    //带选框和文本的对话框
    CHECK,

    //单列表对话框
    LIST,

    //单选对话框
    SINGLE_SELECT,

    //多选对话框
    MULTI_SELECT,

    //带输入框的对话框
    INPUT,

    //带输入框和文本的对话框
    INPUT_EX,

    //短信验证码的对话框
    SMS_CODE
}


/**
 * 消息弹窗
 */
@Composable
fun MessageDialog(
    showDialog: MutableState<Boolean>,
    title: String,
    content: String,
    modifier: Modifier = Modifier,
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    onConfirm: (() -> Unit)? = null,
) {
    if (showDialog.value) {
        AlertDialog(
            onDismissRequest = { showDialog.value = false },
            title = { Text(text = title, fontSize = 16.sp) },
            modifier = modifier.fillMaxWidth(),
            text = { Text(text = content) },
            confirmButton = {
                if (showConfirm) {
                    TextButton(onClick = {
                        showDialog.value = false
                        onConfirm?.invoke()
                    }) {
                        Text(text = confirmText, color = confirmColor)
                    }
                }
            },
            dismissButton = {
                TextButton(onClick = { showDialog.value = false }) {
                    Text(text = cancelText, color = c3367D5)
                }
            },
        )
    }
}

/**
 * 纯列表弹窗
 */
@Composable
fun ListDialog(
    showDialog: MutableState<Boolean>,
    items: List<String>,
    modifier: Modifier = Modifier,
    shape: Shape = AlertDialogDefaults.shape,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onItemClick: ((Int) -> Unit)? = null
) {
    if (showDialog.value) {
        Dialog(onDismissRequest = { showDialog.value = false }) {
            Surface(
                modifier = modifier,
                contentColor = containerColor,
                shape = shape,
                tonalElevation = tonalElevation
            ) {
//                Text(text = "这是标题！",Modifier.padding(20.dp))
                LazyColumn(
                    Modifier
                        .fillMaxSize()
                ) {
                    items.forEachIndexed { index, s ->
                        item {
                            Text(
                                text = s,
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .padding(horizontal = 15.dp, vertical = 10.dp)
                                    .clickable {
                                        onItemClick?.invoke(index)
                                        showDialog.value = false
                                    }, textAlign = TextAlign.Center, color = textContentColor
                            )
                        }
                    }
                }
            }
        }
    }
}

/**
 * 单选弹窗
 */
@Composable
fun LongMessageDialog(
    showDialog: MutableState<Boolean>,
    title: String = "",
    contentMsg: String,
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: (() -> Unit)? = null,
) {
    BasicDialog(
        showDialog = showDialog,
        dialogType = DialogType.LONG_MESSAGE,
        title = title,
        contentMsg = contentMsg,
        confirmColor = confirmColor,
        confirmText = confirmText,
        showConfirm = showConfirm,
        cancelText = cancelText,
        maxContentHeight = maxContentHeight,
        containerColor = containerColor,
        textContentColor = textContentColor,
        tonalElevation = tonalElevation,
        onConfirm = { onConfirm?.invoke() }
    )
}

/**
 * 单选弹窗
 */
@Composable
fun SingleSelectDialog(
    showDialog: MutableState<Boolean>,
    title: String = "",
    contentItems: List<String> = emptyList(),
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: ((Int) -> Unit)? = null,
) {
    BasicDialog(
        showDialog = showDialog,
        dialogType = DialogType.SINGLE_SELECT,
        title = title,
        contentItems = contentItems,
        confirmColor = confirmColor,
        confirmText = confirmText,
        showConfirm = showConfirm,
        cancelText = cancelText,
        maxContentHeight = maxContentHeight,
        containerColor = containerColor,
        textContentColor = textContentColor,
        tonalElevation = tonalElevation,
        onConfirm = { onConfirm?.invoke(it as Int) }
    )
}


/**
 * 多选选弹窗
 */
@Composable
fun MultiSelectDialog(
    showDialog: MutableState<Boolean>,
    title: String = "",
    contentItems: List<String> = emptyList(),
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: ((List<Int>) -> Unit)? = null,
) {
    BasicDialog(
        showDialog = showDialog,
        dialogType = DialogType.MULTI_SELECT,
        title = title,
        contentItems = contentItems,
        confirmColor = confirmColor,
        confirmText = confirmText,
        showConfirm = showConfirm,
        cancelText = cancelText,
        maxContentHeight = maxContentHeight,
        containerColor = containerColor,
        textContentColor = textContentColor,
        tonalElevation = tonalElevation,
        onConfirm = {
            val lst: List<Int> = if (it == null) emptyList() else it as List<Int>
            onConfirm?.invoke(lst)
        }
    )
}

/**
 * 带checkbox弹窗
 */
@Composable
fun CheckboxDialog(
    showDialog: MutableState<Boolean>,
    title: String,
    contentMsg: String,
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: ((Any?) -> Unit)? = null,
) {
    BasicDialog(
        showDialog = showDialog,
        dialogType = DialogType.CHECK,
        title = title,
        contentMsg = contentMsg,
        confirmColor = confirmColor,
        confirmText = confirmText,
        showConfirm = showConfirm,
        cancelText = cancelText,
        maxContentHeight = maxContentHeight,
        containerColor = containerColor,
        textContentColor = textContentColor,
        tonalElevation = tonalElevation,
        onConfirm = onConfirm
    )
}

/**
 * 带输入框弹窗
 */
@Composable
fun InputDialog(
    showDialog: MutableState<Boolean>,
    title: String,
    contentMsg: String = "",
    extMsg: String = "",
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    containerColor: Color = AlertDialogDefaults.containerColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    textInputColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: ((String) -> Unit)? = null,
) {
    BasicDialog(
        showDialog = showDialog,
        dialogType = DialogType.INPUT,
        title = title,
        contentMsg = contentMsg,
        extMsg = extMsg,
        confirmColor = confirmColor,
        confirmText = confirmText,
        showConfirm = showConfirm,
        cancelText = cancelText,
        maxContentHeight = maxContentHeight,
        containerColor = containerColor,
        textContentColor = textContentColor,
        textInputColor = textInputColor,
        tonalElevation = tonalElevation,
        onConfirm = { onConfirm?.invoke((it as String).ifEmpty { contentMsg }) }
    )
}

/**
 * 短信验证码弹窗
 */
@Composable
fun SmsCodeDialog(
    showDialog: MutableState<Boolean>,
    title: String = "",
    onConfirm: ((String) -> Unit)? = null
) {
    BasicDialog(
        showDialog = showDialog,
        title = title,
        dialogType = DialogType.SMS_CODE,
        onConfirm = { onConfirm?.invoke((it as String).ifEmpty { "" }) }
    )
}

/**
 * 带按键弹窗，需要自定内容
 */
@Composable
fun BasicDialog(
    showDialog: MutableState<Boolean>,
    dialogType: DialogType,
    title: String,
    modifier: Modifier = Modifier,
    contentMsg: String = "",
    extMsg: String = "",
    contentItems: List<String> = emptyList(),
    showConfirm: Boolean = true,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = c3367D5,
    maxContentHeight: Dp = 100.dp,
    shape: Shape = AlertDialogDefaults.shape,
    containerColor: Color = AlertDialogDefaults.containerColor,
//    iconContentColor: Color = AlertDialogDefaults.iconContentColor,
    titleContentColor: Color = AlertDialogDefaults.titleContentColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    textInputColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    onConfirm: ((Any?) -> Unit)? = null,
) {
    var callBack: Any? = ""

    ContentDialog(
        showDialog = showDialog,
        title = title,
        modifier = modifier,
        confirmColor = confirmColor,
        confirmText = confirmText,
        cancelText = cancelText,
        showConfirm = showConfirm,
        maxContentHeight = maxContentHeight,
        shape = shape,
        containerColor = containerColor,
//        iconContentColor = iconContentColor,
        titleContentColor = titleContentColor,
//        textContentColor = textContentColor,
        tonalElevation = tonalElevation,
        onConfirm = {
            onConfirm?.invoke(callBack)
        }
    ) {
        when (dialogType) {
            DialogType.SINGLE_SELECT -> {
                SingleSelectContent(items = contentItems) { callBack = it }
            }
            DialogType.MULTI_SELECT -> {
                MultiSelectContent(items = contentItems, textColor = textContentColor) {
                    callBack = it
                }
            }
            DialogType.CHECK -> {
                MessageCheckContent(message = contentMsg, onCheckedChange = { callBack = it })
            }
            DialogType.INPUT, DialogType.INPUT_EX -> {
                MessageInputContent(
                    inputMsg = contentMsg,
                    contentMsg = extMsg,
                    textContentColor = textContentColor,
                    textInputColor = textInputColor
                ) { callBack = it }
            }

            DialogType.SMS_CODE -> {
                SmsCodeContent(
                    modifier = Modifier
                        .height(50.dp),
                    onCompleted = { callBack = it })
            }
            else -> {
                Column(Modifier.verticalScroll(rememberScrollState())) {
                    Text(
                        text = contentMsg,
                        modifier = Modifier.padding(horizontal = 15.dp),
                        color = textContentColor
                    )
                }
            }
        }
    }
}

//手机验证码弹窗
@Composable
private fun SmsCodeContent(modifier: Modifier = Modifier, onCompleted: (String) -> Unit) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center){
        SmsCodeCompose(onCompleted = onCompleted, modifier)
    }
}

/**
 * 多选
 */
@Composable
private fun MultiSelectContent(
    items: List<String>,
    selectIndexes: List<Int> = emptyList(),
    textColor: Color = AlertDialogDefaults.textContentColor,
    onItemsSelect: ((List<Int>) -> Unit)? = null
) {
    var selectItems by remember {
        mutableStateOf(selectIndexes)
    }
    LazyColumn {
        items.forEachIndexed { index, s ->
            item {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 15.dp)
                        .clickable {
                            selectItems = mutableListOf<Int>().apply {
                                addAll(selectItems)
                                if (contains(index)) remove(index) else add(index)
                            }
                            onItemsSelect?.invoke(selectItems)
                        },
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = s,
                        modifier = Modifier.padding(vertical = 10.dp),
                        color = textColor,
                    )
                    Icon(
                        painter = painterResource(id = if (selectItems.contains(index)) com.pj.compose.R.drawable.ic_check_circle else com.pj.compose.R.drawable.ic_radio_button_unchecked),
                        contentDescription = "选择",
                        tint = if (selectItems.contains(index)) MaterialTheme.colorScheme.primary else Color.LightGray
                    )

                }
            }
        }
    }
}

/**
 * 带checkbox
 */
@Composable
fun MessageCheckContent(
    message: String,
    isCheck: Boolean = true,
    textColor: Color = AlertDialogDefaults.textContentColor,
    onCheckedChange: ((Boolean) -> Unit)? = null
) {
    var check by remember {
        mutableStateOf(isCheck)
    }
    Row(verticalAlignment = Alignment.CenterVertically) {
        Checkbox(
            checked = check,
            onCheckedChange = {
                check = it
                onCheckedChange?.invoke(it)
            },
            colors = CheckboxDefaults.colors(checkedColor = c3367D5)
        )
        Text(text = message, modifier = Modifier.clickable {
            check = !check
            onCheckedChange?.invoke(check)
        }, color = textColor)
    }
}


/**
 * 带Input和文本说明
 * TextField详细说明：https://juejin.cn/post/6951563170150350884
 */
@Composable
fun MessageInputContent(
    inputMsg: String = "",
    contentMsg: String = "",
    hint: String = "请输入",
    textInputColor: Color = AlertDialogDefaults.textContentColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    onValueChange: (String) -> Unit
) {
    val valueText = remember {
        mutableStateOf(inputMsg)
    }
    var hasFocus by remember {
        mutableStateOf(false)
    }
    Column {
        BasicTextField(
            value = valueText.value,
            onValueChange = {
                valueText.value = it
                onValueChange(it)
            },
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.Transparent, RoundedCornerShape(5.dp))
                .border(1.dp, Color.LightGray, RoundedCornerShape(5.dp))
                .padding(10.dp)
                .onFocusChanged { hasFocus = it.isFocused },
            textStyle = TextStyle(color = textInputColor),
            decorationBox = @Composable { innerTextField ->
                androidx.compose.foundation.layout.Row(
                    modifier = androidx.compose.ui.Modifier.fillMaxWidth(),
                    verticalAlignment = androidx.compose.ui.Alignment.CenterVertically
                ) {
                    androidx.compose.foundation.layout.Box(
                        modifier = androidx.compose.ui.Modifier.weight(
                            1f
                        )
                    ) {
                        // 当空字符时, 显示hint
                        if (inputMsg.isEmpty())
                            androidx.compose.material.Text(
                                text = hint,
                                color = Color.Gray
                            )

                        // 原本输入框的内容
                        innerTextField()
                    }

                    // 存在焦点 且 有输入内容时. 显示叉号
                    if (hasFocus && inputMsg.isNotEmpty()) {
                        androidx.compose.foundation.Image(
                            imageVector = androidx.compose.material.icons.Icons.Filled.Clear, // 清除图标
                            contentDescription = null,
                            // 点击就清空text
                            modifier = androidx.compose.ui.Modifier.clickable {
                                onValueChange.invoke(
                                    ""
                                )
                            },
                            colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(
                                color = Color.Gray
                            )
                        )
                    }
                }

            }
        )
        if (contentMsg.isNotEmpty()) {
            Column(
                Modifier
                    .padding(top = 10.dp)
                    .verticalScroll(rememberScrollState())
            ) {
                Text(text = contentMsg, color = textContentColor)
            }
        }
    }
}


/**
 * 缺少内容的选择Dialog
 */
@Composable
private fun ContentDialog(
    showDialog: MutableState<Boolean>,
    title: String,
    modifier: Modifier = Modifier,
    contentModifier: Modifier = Modifier,
    showConfirm: Boolean = true,
    cancelColor: Color = MaterialTheme.colorScheme.primary,
    cancelText: String = "取消",
    confirmText: String = "确认",
    confirmColor: Color = MaterialTheme.colorScheme.primary,
    onConfirm: (() -> Unit)? = null,
    maxContentHeight: Dp = 100.dp,
    shape: Shape = AlertDialogDefaults.shape,
    containerColor: Color = AlertDialogDefaults.containerColor,
//    iconContentColor: Color = AlertDialogDefaults.iconContentColor,
    titleContentColor: Color = AlertDialogDefaults.titleContentColor,
//    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    content: @Composable () -> Unit
) {
    if (showDialog.value) {
        Dialog(onDismissRequest = { showDialog.value = false }) {
            Surface(
                modifier = modifier,
                contentColor = containerColor,
                shape = shape,
                tonalElevation = tonalElevation
            ) {
                Column {
                    Text(
                        text = title,
                        modifier = Modifier.padding(20.dp),
                        fontSize = 16.sp,
                        color = titleContentColor
                    )
                    Box(
                        modifier = contentModifier
                            .sizeIn(maxHeight = maxContentHeight)
                            .padding(10.dp)
                    ) { content() }
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.End
                    ) {
                        TextButton(onClick = { showDialog.value = false }) {
                            Text(text = cancelText, color = cancelColor)
                        }
                        if (showConfirm) {
                            TextButton(onClick = {
                                showDialog.value = false
                                onConfirm?.invoke()
                            }) {
                                Text(
                                    text = confirmText,
                                    modifier = Modifier.padding(horizontal = 15.dp),
                                    color = confirmColor
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}


/**
 * 单选
 */
@Composable
private fun SingleSelectContent(
    items: List<String>,
    selectIndex: Int = 0,
    textColor: Color = AlertDialogDefaults.textContentColor,
    onItemSelect: ((Int) -> Unit)? = null
) {
    var selectItem by remember {
        mutableStateOf(selectIndex)
    }
    LazyColumn {
        items.forEachIndexed { index, s ->
            item {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 15.dp)
                        .clickable {
                            selectItem = index
                            onItemSelect?.invoke(index)
                        }, verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = s,
                        modifier = Modifier
                            .padding(vertical = 10.dp)
                            .weight(1f),
                        color = textColor,
                    )
                    if (selectItem == index) {
                        Icon(
                            imageVector = Icons.Default.Check,
                            contentDescription = "选择",
                            tint = Color.Green
                        )
                    }
                }
            }
        }
    }
}


@Preview(showBackground = true)
@Composable
private fun DialogsPagePrev() {
    DialogsPage(navHostController = rememberNavController())
}

@Preview(showBackground = true)
@Composable
private fun MultiSelectContentPrev() {
    MultiSelectContent(listOf("选项1", "选项2", "选项3", "选项4", "选项5"))
}

@Preview(showBackground = true)
@Composable
private fun InputContentPrev() {
    MessageInputContent(inputMsg = "测试一行输入", contentMsg = "这是内容的文本") {

    }
}